<template>
  <div :class="{'upload-component':true,'picture-card':listType == 'picture-card','text':listType == 'text'}">
    <p v-if="title && title === ''" id="uploadTitle">
      {{ title }}
    </p>
    <el-upload
      ref="upload"
      v-loading="loading"
      :class="[no === limit ? 'loadend' : '']"
      :disabled="disabled"
      :data="formData"
      :limit="limit"
      :file-list="newfileList"
      :on-preview="handlePictureCardPreview"
      :on-success="handleSuccess"
      :on-error="handleError"
      :before-upload="beforeUpload"
      :on-remove="handleRemove"
      :before-remove="beforeRemove"
      :action="action"
      :with-credentials="true"
      :accept="accept"
      :list-type="listType"
      class="upload-component-item"
    >
      <!-- 默认是图片 -->
      <em v-if="listType === 'picture-card'" class="el-icon-plus" />
      <!-- 文字,图片形式 -->
      <el-button v-if="listType === 'text' || listType === 'picture'" type="primary">
        点击上传
      </el-button>
      <div v-if="uploadTip" slot="tip" class="el-upload__tip">
        <span>{{ uploadTip }}</span>
      </div>
    </el-upload>
    <el-dialog v-dialogDrag :close-on-click-modal="false" title="查看图片" :visible.sync="dialogVisible" append-to-body>
      <img :src="dialogImageUrl" width="100%" alt="">
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted, inject } from 'vue'
import { ElMessage, ElNotification } from 'element-plus'

const props = defineProps({
  fileType: {
    type: String,
    default: () => 'image' // 上传文件类型 file / image
  },
  limit: { // 上传最大数量
    type: Number,
    default: () => 1
  },
  maxSize: { // 文件上传大小限制，默认5MB
    type: Number,
    default: () => 5
  },
  uploadTip: { // 文字提示
    type: String,
    default: ''
  },
  title: { // 预览图片时的弹窗标题
    type: String,
    default: ''
  },
  valueFormat: { // 双向绑定时，绑定值的格式
    type: String,
    default: 'String'
  },
  accept: { // 接收格式
    type: String,
    default: '.jpg,.jpeg,.png,.bmp,.JPG,.JPEG,.PNG,.BMP'
  },
  listType: { //
    type: String,
    default: 'picture-card'
  },
  fileList: { // 默认显示的图片
    type: Array,
    default: function() {
      // { name: 'default.jpg', path: 'http://wlyd-oss-dev.oss-cn-beijing.aliyuncs.com/platforme6b7023763834767a50fc58e8bb8d1a6_2019-10-29%2016%3A06%3A10_05f076094b36acafef97796572d98d1000e99cd0.jpg?Expires=4725936371&OSSAccessKeyId=LTAI4FtChWzVhNDkx9J7kXRk&Signature=pmvThkGWn7a1VOJADTPWIl%2BOerU%3D' }
      return []
    }
  },
  disabled: { // 是否禁用
    type: Boolean,
    default: false
  },
  formData: {
    type: Object,
    default: () => {
    // "上传必填参数:file文件,那个平台上传,platform,平台; ltp,交易管理平台; oms,订单管理平台; tms,运输管理平台; bms,结算管理平台; ctms: 商贸"
      return { attachmentEnum: 'ctms' }
    }
  },
  textPrewViewWay: {
    type: String,
    default: 'window'
  }
})

const emit = defineEmits(['input', 'change', 'handlePictureCardPreview', 'handleRemove', 'beforeUpload', 'handleSuccess', 'handleError'])

const elForm = inject('elForm', '')
const elFormItem = inject('elFormItem', '')

const upload = ref(null)
const loading = ref(false)
const no = ref(0)
const dialogVisible = ref(false)
const dialogImageUrl = ref('')
const dialogImageTitle = ref('')

// 当前组件的值
const myValue = ref([])

const action = computed(() => {
  if (props.fileType === 'image') {
    return '/upload/fileProcessor/uploadFile'
  } else {
    // return config.uploadUrl + '/FileUpload/upload'
    return '/upload/FileUpload/uploadWithParam'
  }
})

const newfileList = computed(() => {
  const newfileList = []
  props.fileList.forEach(item => {
    if (item.path) {
      newfileList.push({ ...item, url: item.path })
    }
  })
  return newfileList
})

watch(myValue, (newVal) => {
  let value = []
  if (props.valueFormat === 'String') {
    value = newVal.length > 0 ? newVal.map(item => {
      return item.path || item.response.model
    }) : []
  } else if (props.valueFormat === 'Object') {
    value = newVal.length > 0 ? newVal.map(item => {
      return { name: item.name || item.raw.name, path: item.path || item.response.model[0] }
    }) : []
  }
  no.value = newVal.length
  emit('input', value)
  emit('change', value)
  // 触发表单验证
  if (elFormItem) {
    elFormItem.emit('el.form.change', [value])
  }
})

watch(() => props.fileList, (newValue) => {
  myValue.value = [...newfileList.value]
})

onMounted(() => {
  no.value = props.fileList.length
})

/**
 * 点击查看图片的时候触发
 * @params file 文件详细信息
 */
function handlePictureCardPreview(file) {
  if (props.listType === 'text' && props.textPrewViewWay === 'window') {
    const path = file.path || file.response.model[0]
    window.open(path)
  } else {
    dialogImageUrl.value = file.path || file.response.model[0]
    // console.log(file, file.response)
    dialogVisible.value = true
    dialogImageTitle.value = props.title || file.name
    emit('handlePictureCardPreview', file)
  }
}

/**
 * 删除图片之前的时候触发
 * @params arguments[0] 1.准备删除的文件信息
 * @params arguments[0] 2.如果删除之后的文件数组信息
 */
function beforeRemove(file, fileList) {
  // 删除之前
}

/**
 * 删除图片的时候触发
 * @params arguments[0] 1.请求回来的数据
 * @params arguments[0] 2.单文件的数据
 * @params arguments[0] 3.多文件上传时的数组
 */
function handleRemove(file, fileList) {
  // 删除成功
  myValue.value = myValue.value.filter(item => {
    if (file.response && item.response) {
      return item.response.model[0] !== file.response.model[0]
    } else {
      return item.path !== file.path
    }
  })
  // 移除成功
  emit('handleRemove', arguments)
}

/**
 * 上传文件之前的时候触发
 * @params arguments[0] 1.文件信息
 */
function beforeUpload(file) {
  // 上传之前
  const testmsg = file.name.substring(file.name.lastIndexOf('.') + 1)
  const isEnableSize = file.size / 1024 / 1024 < props.maxSize
  const canSubmit = props.accept.includes(testmsg) // 上传图片格式
  if (!canSubmit) {
    ElMessage.error(`只能上传后缀为${props.accept}的文件!`)
    return false
  }

  if (file && String(file.name).length > config.fileNameLimit) {
    ElMessage.error(`上传文件的名称不能超过${config.fileNameLimit}个字!`)
    return false
  }
  if (!isEnableSize) {
    ElMessage.error(`最大${props.fileType === 'file' ? '附件' : '文件'}大小为${props.maxSize}MB，请调整附件大小后再试！`)
    return false
  }
  emit('beforeUpload', file)
  loading.value = isEnableSize && canSubmit

  return isEnableSize && canSubmit
}

/**
 * 上传成功的时候触发
 * @params arguments[0] 1.请求回来的数据
 * @params arguments[0] 2.单文件的数据
 * @params arguments[0] 3.多文件上传时的数组
 */
function handleSuccess(response, file, fileList) {
  loading.value = false
  // 待完善
  if (response.succeed) {
    emit('handleSuccess', { response, file, fileList })
    myValue.value.push(file)
  } else {
    const uploadFileList = upload.value.uploadFiles
    const index = uploadFileList.findIndex(fileItem => {
      return fileItem.uid === file.uid
    })
    uploadFileList.splice(index, 1)
    ElNotification.error({
      title: response.errMsg,
      duration: 2500
    })
  }
}

function handleError() {
  ElMessage.error('上传失败!')
  // 上传失败
  loading.value = false
  emit('handleError', arguments)
}
</script>

<style lang="scss" scoped>
.upload-component{
  ::v-deep
    .loadend{
        .el-upload{
            display: none !important;
        }
    }

    #uploadTitle{
        margin: 0;
        padding: 0;
        line-height: 44px;
        color: #999;
    }

    .el-upload-list__item, .el-upload--picture-card{
        width: 100%;
        height: auto;

        img{
            width: 100%;
            height: auto;
            min-height: 100px;
            max-height: 300px;
        }
    }
}
</style>
